package com.syzg.base.permission.service.impl;

import com.syzg.base.merge.model.Module;
import com.syzg.base.merge.model.Operation;
import com.syzg.base.merge.model.PersonRole;
import com.syzg.base.merge.model.RoleOperation;
import com.syzg.base.module.model.ModuleView;
import com.syzg.base.module.service.ModuleService;
import com.syzg.base.operation.model.OperationView;
import com.syzg.base.operation.service.OperationService;
import com.syzg.base.permission.dao.PermissionDAO;
import com.syzg.base.permission.model.Permission;
import com.syzg.base.permission.service.PermissionService;
import com.syzg.common.config.SysProperties;
import com.syzg.common.exception.BaseException;
import com.syzg.common.service.impl.BaseServiceImpl;
import com.syzg.common.util.SearchMap;
import com.syzg.common.util.MethodUtil;
import com.syzg.core.exception.ServiceException;
import com.syzg.core.util.StringUtil;

import java.util.*;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

@Service("permissionService")
public class PermissionServiceImpl extends BaseServiceImpl<Permission>
    implements PermissionService {
	
	private PermissionDAO permissionDAO;
    private ModuleService moduleService;
    private OperationService operationService;

    public PermissionServiceImpl() {
    }

    @Resource
    public void setModuleService(ModuleService moduleService) {
        this.moduleService = moduleService;
    }

    @Resource
    public void setOperationService(OperationService operationService) {
        this.operationService = operationService;
    }

    @Resource
    public void setPermissionDAO(PermissionDAO permissionDAO){
        super.setDAO(permissionDAO);
        this.permissionDAO = permissionDAO;
    }

    @SuppressWarnings("unchecked")
	public List<Module> findAllModuleOperationForShow() throws ServiceException {
        List<Module> modules = moduleService.findModules();
        List<Operation> operations = operationService.findObjects(SearchMap.forClass(Operation.class));
        Map<String,List<Operation>> map = new HashMap<String,List<Operation>>();
        for(Operation operation : operations){
            String moduleId = String.valueOf(operation.getModule().getId());
            List<Operation> lstOperation = map.get(moduleId);
            if(lstOperation == null){
            	lstOperation = new ArrayList<Operation>();
                map.put(moduleId, lstOperation);
            }
            lstOperation.add(operation);
        }

        List<Module> returnList = new ArrayList<Module>();
        for(Module module : modules){
            List<Operation> tmoOptList = map.get(String.valueOf(module.getId()));
            if(tmoOptList != null){
            	module.setOperations(tmoOptList);
                returnList.add(module);
            }
        }
        return returnList;
    }

    @SuppressWarnings("unchecked")
	public List<ModuleView> findRoleModuleOperationForShow(String roleId)throws ServiceException {
        List<Object[]> modules = permissionDAO.findAllModuleAndSelected(roleId);
        List<Object[]> operations = permissionDAO.findAllOperationAndSelected(roleId);
        Map<String,List<OperationView>> map = new HashMap<String,List<OperationView>>();
        for(Iterator<Object[]> iterator = operations.iterator(); iterator.hasNext();){
            Object[] operationObj = (Object[])iterator.next();
            Operation operation = (Operation)operationObj[0];
            String flgSelected = (String)operationObj[1];
            OperationView operationView = new OperationView();
            try{
                MethodUtil.copyProperties(operationView, operation);
            } catch(Exception e){
                e.printStackTrace();
                throw new BaseException(e);
            }
            operationView.setIsSelected(flgSelected);
            String moduleId = String.valueOf(operation.getModule().getId());
            List<OperationView> lstOperationView = (List<OperationView>)map.get(moduleId);
            if(lstOperationView == null){
            	lstOperationView = new ArrayList<OperationView>();
                map.put(moduleId, lstOperationView);
            }
            lstOperationView.add(operationView);
        }

        List<ModuleView> returnList = new ArrayList<ModuleView>();
        for(Iterator<Object[]> iterator1 = modules.iterator(); iterator1.hasNext();){
            Object moduleObj[] = (Object[])iterator1.next();
            Module module = (Module)moduleObj[0];
            String flgSelected = (String)moduleObj[1];
            ModuleView moduleView = new ModuleView();
            try{
                MethodUtil.copyProperties(moduleView, module);
            } catch(Exception e) {
                e.printStackTrace();
                throw new BaseException(e);
            }
            moduleView.setIsSelected(flgSelected);
            List<OperationView> tmpOptList = map.get(String.valueOf(moduleView.getId()));
            if(tmpOptList != null){
                moduleView.setOperationViews(tmpOptList);
            	returnList.add(moduleView);
            }
        }
        return returnList;
    }

    public boolean verifyPersonPermission(String personId, String moduleCode, String operationCode)
        throws ServiceException {
        if(StringUtil.isBlank(moduleCode) || StringUtil.isBlank(operationCode))
            return false;
        else
            return permissionDAO.verifyPersonPermission(personId, moduleCode, operationCode);
    }

    @SuppressWarnings("unchecked")
	public List getPersonPermission(String personId) {
        List permCodeList = new ArrayList();
        List<Object> list = permissionDAO.getPersonPermission(personId);
        Object permCodes[];
        for(Iterator iterator = list.iterator(); iterator.hasNext(); permCodeList.add((new StringBuilder(String.valueOf((String)permCodes[0]))).append("_").append((String)permCodes[1]).toString()))
            permCodes = (Object[])iterator.next();

        return permCodeList;
    }

    @SuppressWarnings("unchecked")
	public List getAllPermission() {
        return permissionDAO.getAllPermission();
    }

    @SuppressWarnings("unchecked")
	public List<Module> findModulesByPersonId(String personId)throws ServiceException {
        List<Module> moduleList = null;
        if(personId != null && personId.equals(SysProperties.ADMIN_ID)){
            moduleList = moduleService.findModules();
        } else {
            //moduleList = permissionDAO.findModulesByPersonId(personId);
            SearchMap searchMap = SearchMap.forClass(PersonRole.class);
        	searchMap.eq("a.person.id", personId);
        	searchMap.addProperty("a.role.id");
        	List<Object> lstRoleId = moduleService.findObjects(searchMap);
        	
        	searchMap = SearchMap.forClass(RoleOperation.class);
        	searchMap.in("a.role.id", lstRoleId);
        	searchMap.addProperty("a.operation.id");
        	List<Object> lstOperationId = moduleService.findObjects(searchMap);
        	
        	searchMap = SearchMap.forClass(Operation.class);
        	searchMap.in("a.id", lstOperationId);
        	searchMap.addProperty("a.module.id");
        	List<Object> lstModuleId = moduleService.findObjects(searchMap);
        	
        	searchMap = SearchMap.forClass(Module.class);
        	searchMap.in("a.id", lstModuleId);
        	searchMap.addOrder("a.parentModule.id", SearchMap.ORDER_ASC);
        	searchMap.addOrder("a.orderNo", SearchMap.ORDER_ASC);
        	moduleList = moduleService.findObjects(searchMap);
        	
        	searchMap = SearchMap.forClass(Module.class);
        	searchMap.eq("a.parentModule.id", "0");
        	List<Module> lstPModule = moduleService.findObjects(searchMap);
        	
        	Map<String,String> map = new HashMap<String, String>();
        	for(Module module : moduleList){
        		map.put(module.getParentModule().getId(), "1");
        	}
        	List<Module> moduleListTemp = new ArrayList<Module>();
        	for(Module module : lstPModule){
        		if(map.get(module.getId())!=null){
        			moduleListTemp.add(module);
        		}
        	}
        	for(Module module : moduleList){
        		moduleListTemp.add(module);
        	}
        	moduleList = moduleListTemp;
        }
        return moduleList;
    }

    @SuppressWarnings("unchecked")
	private Set appendParentModule(List allModuleList, List moduleList) throws ServiceException {
        Set newList = new HashSet();
        if(moduleList == null || moduleList.isEmpty()){
            return newList;
        }
        List tmpList = new ArrayList();
        for(Iterator iterator = allModuleList.iterator(); iterator.hasNext();){
            Module tmpModule = (Module)iterator.next();
            for(Iterator iterator1 = moduleList.iterator(); iterator1.hasNext();){
                Module module = (Module)iterator1.next();
                if(module.getParentModule() == null){
                	Module pModule = new Module();
                	pModule.setParentModule(pModule);
                	pModule.setId("0");
                	module.setParentModule(pModule);
                }
                if(tmpModule.getId() != null && module.getParentModule().getId().equals(tmpModule.getId())){
                    tmpList.add(tmpModule);
                }
            }
        }

        if(!tmpList.isEmpty()) {
            newList.addAll(tmpList);
            newList.addAll(appendParentModule(allModuleList, tmpList));
        }
        return newList;
    }
}